"""轻量化AI视频编码分析系统 - 主程序入口"""

import os
import sys
import argparse
import logging
import time
from typing import List, Dict, Any

# 添加项目根目录到Python路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

# 导入自定义模块
from src.config_loader import config_loader
from src.utils import get_video_files, ensure_directory
from src.video_analyzer import VideoAnalyzer
from src.text_completer import TextCompleter
from src.encoding_processor import EncodingProcessor
from src.result_exporter import ResultExporter

# 配置日志
logging.basicConfig(
    level=getattr(logging, config_loader.get("logging.level", "INFO")),
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)


def parse_arguments() -> argparse.Namespace:
    """解析命令行参数
    
    Returns:
        解析后的参数命名空间
    """
    parser = argparse.ArgumentParser(description='轻量化AI视频编码分析系统')
    
    # 输入参数
    input_group = parser.add_argument_group('输入参数')
    # 设置默认输入路径为../data/MP4/
    input_group.add_argument('--input', '-i', type=str, 
                           default='../data/MP4/', 
                           help='输入视频文件路径或目录 (默认: ../data/MP4/)')
    input_group.add_argument('--url', '-u', type=str, help='单个视频URL')
    input_group.add_argument('--batch', '-b', type=str, help='批量处理文件列表')
    
    # 配置参数
    config_group = parser.add_argument_group('配置参数')
    config_group.add_argument('--config', '-c', type=str, default='.env', help='环境变量配置文件')
    # 设置默认样本数据路径为../data/样本数据表.csv
    config_group.add_argument('--sample-data', type=str, 
                            default='../data/样本数据表.csv', 
                            help='样本数据CSV文件路径 (默认: ../data/样本数据表.csv)')
    
    # 输出参数
    output_group = parser.add_argument_group('输出参数')
    output_group.add_argument('--output', '-o', type=str, help='输出目录')
    output_group.add_argument('--format', '-f', type=str, default='txt', choices=['txt'], help='输出格式')
    
    # 处理参数
    process_group = parser.add_argument_group('处理参数')
    process_group.add_argument('--skip-analysis', action='store_true', help='跳过视频分析（仅进行编码处理）')
    process_group.add_argument('--skip-completion', action='store_true', help='跳过文本补充')
    process_group.add_argument('--verify', action='store_true', help='验证输出结果')
    
    # 日志参数
    log_group = parser.add_argument_group('日志参数')
    log_group.add_argument('--log-level', type=str, choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'], help='日志级别')
    log_group.add_argument('--log-file', type=str, help='日志文件路径')
    
    args = parser.parse_args()
    
    # 只有当用户明确提供了参数但都为空时才报错（保留原行为）
    # 这样可以保持向后兼容性
    if len(sys.argv) > 1 and not any([args.input, args.url, args.batch]):
        parser.error('必须提供输入源: --input、--url 或 --batch')
    
    return args


def initialize_components(args: argparse.Namespace) -> Dict[str, Any]:
    """初始化各个组件
    
    Args:
        args: 命令行参数
    
    Returns:
        组件字典
    """
    components = {}
    
    # 获取DeepSeek API密钥（用于文本补充）
    deepseek_api_key = config_loader.get_api_key("deepseek")
    if not deepseek_api_key:
        logger.warning("DeepSeek API密钥未配置，请在.env文件中设置DEEPSEEK_API_KEY")
    
    # 获取智谱API密钥（用于视频分析）
    zhipuai_api_key = config_loader.get("api.zhipuai.api_key")
    if not zhipuai_api_key:
        logger.warning("智谱API密钥未配置，请在.env文件中设置ZHIPUAI_API_KEY")
    
    # 初始化视频分析器
    if not args.skip_analysis:
        # 从配置中获取智谱API参数
        zhipuai_config = config_loader.get("api.zhipuai", {})
        
        # 优先从环境变量获取模型名称
        model_name = os.getenv("ZHIPUAI_MODEL_NAME")
        
        # 如果环境变量未设置，则从配置获取视觉模型列表的第一个模型
        if not model_name:
            vision_models = zhipuai_config.get("vision_models", ["GLM-4V-Flash"])
            model_name = vision_models[0] if vision_models else "GLM-4V-Flash"
        
        components['analyzer'] = VideoAnalyzer(
            api_key=zhipuai_config.get("api_key"),
            api_url=zhipuai_config.get("url"),
            max_retries=zhipuai_config.get("max_retries"),
            retry_delay=zhipuai_config.get("retry_delay"),
            model_name=model_name
        )
        logger.info(f"视频分析器初始化完成，使用模型: {model_name}")
    
    # 初始化文本补充器（如果提供了样本数据）
    if not args.skip_completion and args.sample_data and deepseek_api_key:
        if os.path.exists(args.sample_data):
            components['completer'] = TextCompleter(
                api_key=deepseek_api_key,
                sample_data_path=args.sample_data,
                max_retries=config_loader.get("api.deepseek.max_retries", 3),
                retry_delay=config_loader.get("api.deepseek.retry_delay", 5)
            )
            logger.info("文本补充器初始化完成")
        else:
            logger.warning(f"样本数据文件不存在: {args.sample_data}，将跳过文本补充")
    elif not args.skip_completion and args.sample_data:
        logger.warning("DeepSeek API密钥未配置，将跳过文本补充")
    
    # 初始化编码处理器
    components['encoding_processor'] = EncodingProcessor()
    logger.info("编码处理器初始化完成")
    
    # 初始化结果输出器
    output_dir = args.output if args.output else config_loader.get_results_path()
    ensure_directory(output_dir)
    components['exporter'] = ResultExporter(output_dir)
    logger.info(f"结果输出器初始化完成，输出目录: {output_dir}")
    
    return components


def process_single_video(video_source: str, is_url: bool, components: Dict[str, Any], args: argparse.Namespace) -> Dict[str, Any]:
    """处理单个视频
    
    Args:
        video_source: 视频源（文件路径或URL）
        is_url: 是否为URL
        components: 组件字典
        args: 命令行参数
    
    Returns:
        处理结果
    """
    logger.info(f"开始处理 {'URL' if is_url else '文件'}: {video_source}")
    start_time = time.time()
    
    result = {}
    validation_warnings = []
    
    try:
        # 步骤1: 视频分析
        if 'analyzer' in components:
            if is_url:
                # 如果是URL，需要先下载或处理，目前先使用通用方法
                result = components['analyzer'].analyze_video(video_source)
            else:
                result = components['analyzer'].analyze_video(video_source)
            logger.info(f"视频分析完成，耗时: {time.time() - start_time:.2f}秒")
        else:
            # 如果跳过分析，初始化基础信息
            result = {
                '视频URL' if is_url else '视频文件': video_source,
                '分析时间': time.strftime('%Y-%m-%d %H:%M:%S')
            }
        
        # 提取视频ID
        from src.utils import extract_video_id
        video_id = extract_video_id(os.path.basename(video_source)) if not is_url else video_source
        result['视频ID'] = video_id
        
        # 步骤2: 文本补充
        if 'completer' in components:
            result = components['completer'].complete_text(result, video_id)
            logger.info(f"文本补充完成，耗时: {time.time() - start_time:.2f}秒")
        
        # 步骤3: 编码处理
        result, warnings = components['encoding_processor'].process_encoding(result)
        validation_warnings.extend(warnings)
        logger.info(f"编码处理完成，耗时: {time.time() - start_time:.2f}秒")
        
        # 步骤4: 验证结果完整性
        completeness_warnings = components['encoding_processor'].validate_result_completeness(result)
        validation_warnings.extend(completeness_warnings)
        
        # 添加验证信息
        result['验证警告'] = len(validation_warnings)
        result['处理状态'] = '成功' if not any(w['level'] == 'error' for w in validation_warnings) else '有错误'
        
        # 步骤5: 导出结果
        if args.format == 'txt':
            export_path = components['exporter'].export_to_txt(result, video_id)
            result['导出文件'] = export_path
            
            # 验证导出
            if args.verify:
                if components['exporter'].verify_export(export_path):
                    result['导出验证'] = '通过'
                else:
                    result['导出验证'] = '失败'
        
        logger.info(f"视频处理完成，总耗时: {time.time() - start_time:.2f}秒")
        
        # 输出验证警告摘要
        if validation_warnings:
            error_count = sum(1 for w in validation_warnings if w['level'] == 'error')
            warning_count = sum(1 for w in validation_warnings if w['level'] == 'warning')
            info_count = sum(1 for w in validation_warnings if w['level'] == 'info')
            logger.info(f"验证结果: {error_count}个错误, {warning_count}个警告, {info_count}个信息")
    
    except Exception as e:
        logger.error(f"处理视频时出错: {str(e)}")
        result = {
            '视频ID': video_id,
            '处理状态': '失败',
            '错误信息': str(e)
        }
    
    return result


def process_batch(batch_file: str, components: Dict[str, Any], args: argparse.Namespace) -> List[Dict[str, Any]]:
    """批量处理视频
    
    Args:
        batch_file: 包含视频列表的文件路径
        components: 组件字典
        args: 命令行参数
    
    Returns:
        处理结果列表
    """
    logger.info(f"开始批量处理，文件列表: {batch_file}")
    
    results = []
    
    try:
        # 读取文件列表
        with open(batch_file, 'r', encoding='utf-8') as f:
            video_sources = [line.strip() for line in f if line.strip()]
        
        logger.info(f"共读取到 {len(video_sources)} 个视频源")
        
        # 逐个处理
        for i, video_source in enumerate(video_sources, 1):
            logger.info(f"处理项目 {i}/{len(video_sources)}")
            
            # 判断是否为URL
            is_url = video_source.startswith(('http://', 'https://'))
            
            # 处理单个视频
            result = process_single_video(video_source, is_url, components, args)
            results.append(result)
        
        # 生成汇总报告
        if results:
            batch_name = os.path.splitext(os.path.basename(batch_file))[0]
            summary_path = components['exporter'].export_summary(results, f"{batch_name}_summary.txt")
            logger.info(f"批量处理完成，汇总报告: {summary_path}")
            
            # 统计处理结果
            success_count = sum(1 for r in results if r.get('处理状态') == '成功')
            error_count = len(results) - success_count
            logger.info(f"批量处理统计: 成功 {success_count}, 失败 {error_count}")
    
    except Exception as e:
        logger.error(f"批量处理时出错: {str(e)}")
    
    return results


def main():
    """主函数"""
    logger.info("轻量化AI视频编码分析系统启动")
    
    try:
        # 步骤1: 解析命令行参数
        args = parse_arguments()
        
        # 添加调试日志，输出使用的参数
        logger.debug(f"使用的输入路径: {args.input}")
        logger.debug(f"使用的样本数据路径: {args.sample_data}")
        logger.debug(f"使用的输出格式: {args.format}")
        logger.debug(f"是否跳过分析: {args.skip_analysis}")
        logger.debug(f"是否跳过补充: {args.skip_completion}")
        
        # 步骤2: 更新日志配置
        if args.log_level:
            config_loader.set("logging.level", args.log_level)
            logging.getLogger().setLevel(getattr(logging, args.log_level))
            logger.debug(f"日志级别已更新为: {args.log_level}")
        
        if args.log_file:
            # 添加文件日志处理器
            file_handler = logging.FileHandler(args.log_file, encoding='utf-8')
            file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
            logging.getLogger().addHandler(file_handler)
            logger.info(f"日志文件已设置: {args.log_file}")
        
        # 步骤3: 初始化组件
        logger.debug("开始初始化组件...")
        components = initialize_components(args)
        logger.debug(f"组件初始化完成，已加载的组件: {list(components.keys())}")
        
        # 步骤4: 执行处理
        results = []
        
        # 处理单个URL
        if args.url:
            logger.debug(f"开始处理URL: {args.url}")
            result = process_single_video(args.url, True, components, args)
            results.append(result)
        
        # 处理单个文件或目录
        elif args.input:
            logger.debug(f"开始处理输入路径: {args.input}")
            if os.path.exists(args.input):
                logger.debug(f"输入路径存在: {args.input}")
                if os.path.isdir(args.input):
                    logger.debug(f"输入路径是目录，准备获取视频文件列表...")
                    # 处理目录中的所有视频文件
                    video_files = get_video_files(args.input)
                    logger.info(f"在目录中找到 {len(video_files)} 个视频文件")
                    logger.debug(f"找到的视频文件列表: {video_files}")
                    
                    for video_file in video_files:
                        logger.debug(f"处理视频文件: {video_file}")
                        result = process_single_video(video_file, False, components, args)
                        results.append(result)
                    
                    # 生成汇总报告
                    if results:
                        summary_path = components['exporter'].export_summary(results, "directory_summary.txt")
                        logger.info(f"目录处理完成，汇总报告: {summary_path}")
                else:
                    logger.debug(f"输入路径是文件: {args.input}")
                    # 处理单个文件
                    result = process_single_video(args.input, False, components, args)
                    results.append(result)
            else:
                logger.warning(f"输入路径不存在: {args.input}")
                results.append({
                    '文件路径': args.input,
                    '处理状态': '失败',
                    '错误信息': '文件或目录不存在'
                })
        
        # 批量处理
        elif args.batch:
            results = process_batch(args.batch, components, args)
        
        # 步骤5: 输出处理结果摘要
        if results:
            success_count = sum(1 for r in results if r.get('处理状态') in ['成功', '有错误'])
            error_count = len(results) - success_count
            
            logger.info("=" * 50)
            logger.info("处理完成")
            logger.info(f"总处理数量: {len(results)}")
            logger.info(f"成功数量: {success_count}")
            logger.info(f"失败数量: {error_count}")
            logger.info("=" * 50)
        
    except KeyboardInterrupt:
        logger.info("程序被用户中断")
    except Exception as e:
        logger.error(f"程序运行出错: {str(e)}")
        import traceback
        logger.error(traceback.format_exc())
        sys.exit(1)
    
    logger.info("程序正常结束")


if __name__ == "__main__":
    main()
